/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.control;

import org.zhiqim.kernel.Z;
import org.zhiqim.kernel.config.Group;
import org.zhiqim.kernel.config.Item;
import org.zhiqim.kernel.logging.Log;
import org.zhiqim.kernel.logging.LogFactory;
import org.zhiqim.kernel.model.maps.HashMapCV;
import org.zhiqim.kernel.model.maps.MapCV;
import org.zhiqim.kernel.util.Randoms;

/**
 * 对象处理线程池控制器，指定池最小值、最大值、初始值，允许线程空闲时长和允许缓存对象大小<br><br>
 * 1.创建时创建初始值大小的线程池，创建对象队列，和主线程<br>
 * 2.其他线程通过post传递对象可执行对象<br>
 * 3.主线程调度线程池处理对象，并检查线程池空闲线程
 *
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
public class HandlerController extends ThreaderController
{
    private static final Log log = LogFactory.getLog(HandlerController.class);
    private static final String DEFAULT = "default";
    
    private Handler<?> defaultHandler = null;          //缺省处理器
    private Handler<Object> rejectHandler = null;           //拒绝处理器
    private final MapCV<Handler<?>> handlerMap = new HashMapCV<>();
    
    public HandlerController()
    {
        setThreadName("Handler-" + Randoms.upperLetters(1)+Randoms.lowerLettersDigits(3));
    }
    
    /*************************************************************************************************/
    //创建&销毁，支持通过配置key=class,value=handler方式
    /*************************************************************************************************/
    
    @Override
    public boolean openBefore()
    {
        super.openBefore();
        
        if (id == null)
        {//没有配置服务
            return true;
        }
        
        Group group = Z.conf().group(id+".handler");
        if (group == null || group.isEmpty())
        {//没有配置处理器
            return true;
        }

        for (Item item : group.list())
        {
            String className = item.getKey();
            String handlerName = item.getString();

            Object handler = Z.cls().newInstance(handlerName);
            if (handler == null || !(handler instanceof Handler))
            {
                log.error("配置[%s]中，[%s]类不存在或未实现Handler接口", group.getId(), handlerName);
                return false;
            }
            
            if (DEFAULT.equals(className))
            {//默认类名
                setDefaultHandler((Handler<?>)handler);
            }
            else
            {//指定类名
                Class<?> cls = Z.cls().forName(className);
                if (cls == null)
                {
                    log.error("配置[%s]中，[%s]类不存在", group.getId(), className);
                    return false;
                }
                handlerMap.put(cls, (Handler<?>)handler);
            }
        }
        
        return true;
    }
    
    @Override
    public void closeAfter()
    {
        super.closeAfter();
        
        defaultHandler = null;
        handlerMap.clear();
    }
    
    @Override
    public HandlerController set(int poMinSize, int poMaxSize, int poIdleTime, int poQueueSize)
    {
        super.set(poMinSize, poMaxSize, poIdleTime, poQueueSize);
        return this;
    }
    
    /*************************************************************************************************/
    //增加&删除处理器
    /*************************************************************************************************/
    
    /** 判断是否有缺省处理器 */
    public boolean hasDefaultHandler()
    {
        return defaultHandler != null;
    }
    
    /** 设置缺省处理器 */
    public <T> void setDefaultHandler(Handler<T> handler)
    {
        defaultHandler = handler;
    }
    
    /** 清除缺省处理器 */
    public void clearDefaultHandler()
    {
        defaultHandler = null;
    }
    
    /** 判断是否有拒绝处理器 */
    public boolean hasRejectHandler()
    {
        return rejectHandler != null;
    }
    
    /** 设置拒绝处理器，警告：拒绝处理器中不能作业务处理，否则会阻塞调用线程 */
    public void putRejectHandler(Handler<Object> handler)
    {
        rejectHandler = handler;
    }
    
    /** 设置拒绝处理器，警告：拒绝处理器中不能作业务处理，否则会阻塞调用线程，当不存在拒绝处理器时 */
    public void setRejectHandler(Handler<Object> handler)
    {
        if (rejectHandler != null)
            return;
        
        rejectHandler = handler;
    }

    /** 清除拒绝处理器 */
    public void clearRejectHandler()
    {
        rejectHandler = null;
    }
    
    /** 判断是否存在事件处理器 */
    public boolean hasHandler(Class<?> eventClass)
    {
        return handlerMap.containsKey(eventClass);
    }

    /** 增加一个事件处理器 */
    public <T> void putHandler(Class<T> eventClass, Handler<T> handler)
    {
        handlerMap.put(eventClass, handler);
    }
    
    /** 增加一个事件处理器，当不存在的时候添加 */
    public <T> void addHandler(Class<T> eventClass, Handler<T> handler)
    {
        if (handlerMap.containsKey(eventClass))
            return;
        
        handlerMap.put(eventClass, handler);
    }

    /** 删除一个事件处理器 */
    public <T> void removeHandler(Class<T> eventClass)
    {
        handlerMap.remove(eventClass);
    }
    
    /** 获取一个事件处理器 */
    @SuppressWarnings("unchecked")
    public <T> Handler<T> getHandler(Class<T> eventClass)
    {
        return (Handler<T>)handlerMap.get(eventClass);
    }
    
    /*************************************************************************************************/
    //公开的对象处理方法
    /*************************************************************************************************/
    
    /** 处理一个事件，转化为Handlee由父类处理 */
    public boolean execute(Object event)
    {
        return execute(event, false);
    }
    
    /** 处理一个事件，并提供优先参数，转化为Handlee由父类处理 */
    public boolean execute(Object event, boolean priority)
    {
        Handler<?> handler = handlerMap.get(event.getClass());
        if (handler == null)
            handler = defaultHandler;
            
        if (handler == null)
        {
            log.fatal("事件处理器[%s]未配置处理器", event.getClass().getName());
            return false;
        }
        
        Handlee<?> command = new Handlee<>(event, handler);
        if (super.execute(command, priority))
            return true;
        
        if (rejectHandler == null)
            return false;
        
        rejectHandler.process(event);
        return false;
    }
}
